package utils

/*
 +----------------------------------------------------------------------
 + Title        : NacosRegisterServer
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2022-01-06
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : nacos 服务注册与发现
 +				: 文档地址: https://github.com/nacos-group/nacos-sdk-go/blob/master/README_CN.md
 +				: 插件:
 +				: 		github.com/nacos-group/nacos-sdk-go/clients
 +				: 		github.com/nacos-group/nacos-sdk-go/common/constant
 +				: 		github.com/nacos-group/nacos-sdk-go/vo
 +----------------------------------------------------------------------
*/
import (
	"github.com/nacos-group/nacos-sdk-go/clients"
	"github.com/nacos-group/nacos-sdk-go/clients/naming_client"
	"github.com/nacos-group/nacos-sdk-go/model"
	"github.com/nacos-group/nacos-sdk-go/vo"
)

// 定义NACOS服务注册与发现结构体
type NacosServiceRegisterAndDiscovery struct {
	namingClient naming_client.INamingClient
}

/**
 * 创建NACOS服务注册
 *
 * @return *NacosServiceRegisterAndDiscovery, error
 * @author huwl
 */
func NewNacosServiceRegister() (*NacosServiceRegisterAndDiscovery, error) {
	// 创建服务发现客户端的
	namingClient, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig:  &NacosClientConfig,
			ServerConfigs: NacosServerConfigs,
		},
	)
	if err != nil {
		return nil, err
	}

	return &NacosServiceRegisterAndDiscovery{
		namingClient: namingClient,
	}, nil
}

/**
 * 创建NACOS服务发现
 *
 * @return *NacosServiceRegisterAndDiscovery, error
 * @author huwl
 */
func NewNacosServiceDiscovery() (*NacosServiceRegisterAndDiscovery, error) {
	// 创建服务发现客户端的
	namingClient, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig:  &NacosClientConfig,
			ServerConfigs: NacosServerConfigs,
		},
	)
	if err != nil {
		return nil, err
	}

	return &NacosServiceRegisterAndDiscovery{
		namingClient: namingClient,
	}, nil
}

/**
 * 注册服务
 *
 * @param string serviceHost ------------------------------------------必传
 * @param uint64 servicePort ------------------------------------------必传
 * @param string serviceName ------------------------------------------必传
 * @param string clusterName ------------------------------------------必传
 * @param string groupName --------------------------------------------必传
 * @return bool, error
 * @author huwl
 */
func (sr *NacosServiceRegisterAndDiscovery) RegisterService(serviceHost string, servicePort uint64, serviceName, clusterName, groupName string) (bool, error) {
	// 注册实例
	return sr.namingClient.RegisterInstance(vo.RegisterInstanceParam{
		Ip:          serviceHost,
		Port:        servicePort,
		ServiceName: serviceName,
		Weight:      1,
		Enable:      true,
		Healthy:     true,
		Ephemeral:   true,
		Metadata:    map[string]string{"idc": "shanghai"},
		ClusterName: clusterName, // 默认值: DEFAULT
		GroupName:   groupName,   // 默认值: DEFAULT_GROUP
	})
}

/**
 * 注销服务
 *
 * @param string serviceHost ------------------------------------------必传
 * @param uint64 servicePort ------------------------------------------必传
 * @param string serviceName ------------------------------------------必传
 * @param string clusterName ------------------------------------------必传
 * @param string groupName --------------------------------------------必传
 * @return bool, error
 * @author huwl
 */
func (sr *NacosServiceRegisterAndDiscovery) NacosDeregisterInstance(serviceHost string, servicePort uint64, serviceName, clusterName, groupName string) (bool, error) {
	return sr.namingClient.DeregisterInstance(vo.DeregisterInstanceParam{
		Ip:          serviceHost,
		Port:        servicePort,
		ServiceName: serviceName,
		Ephemeral:   true,
		Cluster:     clusterName, // 默认值DEFAULT
		GroupName:   groupName,   // 默认值DEFAULT_GROUP
	})
}

/**
 * 获取一个健康的实例（加权随机轮询）
 * SelectOneHealthyInstance将会按加权随机轮询的负载均衡策略返回一个健康的实例
 * 实例必须满足的条件：health=true,enable=true and weight>0
 *
 * @param string serviceName ------------------------------------------必传
 * @param string groupName --------------------------------------------必传
 * @param []string clusters -------------------------------------------必传
 * @return *model.Instance error
 * @author huwl
 */
func (sr *NacosServiceRegisterAndDiscovery) NacosSelectOneHealthyInstance(serviceName, groupName string, clusters []string) (*model.Instance, error) {
	return sr.namingClient.SelectOneHealthyInstance(vo.SelectOneHealthInstanceParam{
		ServiceName: serviceName,
		// GroupName:   "group-a",             // 默认值:DEFAULT_GROUP
		GroupName: groupName, // 默认值DEFAULT_GROUP
		// Clusters:    []string{"cluster-a"}, // 默认值:DEFAULT
		Clusters: clusters, // 默认值:DEFAULT
	})
}

/**
 * 获取服务信息
 *
 * @param string serviceName ------------------------------------------必传
 * @param string groupName --------------------------------------------必传
 * @param []string clusters -------------------------------------------必传
 * @return model.Service error
 * @author huwl
 */
func (sr *NacosServiceRegisterAndDiscovery) NacosGetService(serviceName, groupName string, clusters []string) (model.Service, error) {
	return sr.namingClient.GetService(vo.GetServiceParam{
		ServiceName: serviceName,
		// Clusters:    []string{"cluster-a"}, // 默认值DEFAULT
		// GroupName:   "group-a",             // 默认值DEFAULT_GROUP
		GroupName: groupName, // 默认值DEFAULT_GROUP
		Clusters:  clusters,  // 默认值DEFAULT
	})
}

/**
 * 获取所有的实例列表
 *
 * @param string serviceName ------------------------------------------必传
 * @param string groupName --------------------------------------------必传
 * @param []string clusters -------------------------------------------必传
 * @return []model.Instance error
 * @author huwl
 */
func (sr *NacosServiceRegisterAndDiscovery) NacosSelectAllInstances(serviceName, groupName string, clusters []string) ([]model.Instance, error) {
	return sr.namingClient.SelectAllInstances(vo.SelectAllInstancesParam{
		ServiceName: serviceName,
		// Clusters:    []string{"cluster-a"}, // 默认值DEFAULT
		// GroupName:   "group-a",             // 默认值DEFAULT_GROUP
		GroupName: groupName, // 默认值DEFAULT_GROUP
		Clusters:  clusters,  // 默认值DEFAULT
	})
}

/**
 * 获取实例列表
 *
 * @param string serviceName ------------------------------------------必传
 * @param string groupName --------------------------------------------必传
 * @param []string clusters -------------------------------------------必传
 * @return []model.Instance error
 * @author huwl
 */
func (sr *NacosServiceRegisterAndDiscovery) NacosSelectInstances(serviceName, groupName string, clusters []string) ([]model.Instance, error) {
	return sr.namingClient.SelectInstances(vo.SelectInstancesParam{
		ServiceName: serviceName,
		// Clusters:    []string{"cluster-a"}, // 默认值DEFAULT
		// GroupName:   "group-a",             // 默认值DEFAULT_GROUP
		GroupName:   groupName, // 默认值DEFAULT_GROUP
		Clusters:    clusters,  // 默认值DEFAULT
		HealthyOnly: true,
	})
}

/**
 * 获取实例列表
 *
 * @param string nameSpace --------------------------------------------必传
 * @param uint32 pageNo -----------------------------------------------必传
 * @param uint32 pageSize ---------------------------------------------必传
 * @return model.ServiceList error
 * @author huwl
 */
func (sr *NacosServiceRegisterAndDiscovery) NacosGetAllServicesInfo(nameSpace string, pageNo, pageSize uint32) (model.ServiceList, error) {
	return sr.namingClient.GetAllServicesInfo(vo.GetAllServiceInfoParam{
		NameSpace: nameSpace,
		PageNo:    pageNo,
		PageSize:  pageSize,
	})
}
